package com.boarsoft.config.core;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boarsoft.common.Util;
import com.boarsoft.common.util.FileUtil;
import com.boarsoft.common.util.HttpClientUtil;

/**
 * 应用配置变量和配置文件初始化服务
 *
 * @author Mac_J
 */
public class ConfigHttpPuller {
	private static final Logger log = LoggerFactory.getLogger(ConfigHttpPuller.class);
	public static String varPullUrl = "http://%s/config/var/list2.do?appId=%s&appCode=%s&instanceId=%s&env=%s";
	public static String pullVars = "http://%s/config/var/list2.do?appCode=%s";
	public static String filePullUrl = "http://%s/config/file/list2.do?env=%s&group=%s&appId=%s&appCode=%s&instanceId=%s";
	public static String fileContentUrl = "http://%s/config/file/version/content.do?id=%s";
	public static String fileDownloadUrl = "http://%s/config/file/version/download.do?id=%s&key=%s";

	public static List<Config> getConfig(String groupId) {
		String url = String.format(pullVars, groupId);
		String json = HttpClientUtil.sendGet(url);
		if (Util.strIsEmpty(json)) {
			return new ArrayList<>();
		}
		List<Config> res=new ArrayList<>();
		JSONObject jo = (JSONObject) JSON.parse(json);
		if (jo.getBooleanValue("success")) {
			JSONArray data = (JSONArray) jo.get("data");
			for (Object o : data) {
				JSONObject vo = (JSONObject) o;
				String k = vo.getString("name");
				String v = vo.getString("value");
				String g = vo.getString("group");
				Config config=new Config();
				config.setGroup(g);
				config.setName(k);
				config.setValue(v);
				res.add(config);
			}
		}
		return res;
	}



	public static String getConfigFile(String namespace) {
		String url = String.format(fileContentUrl, namespace);
		String json = HttpClientUtil.sendGet(url);
		if (Util.strIsEmpty(json)) {
			return null;
		}
		JSONObject jo = (JSONObject) JSON.parse(json);
		if (jo.getBooleanValue("success")) {
			return (String) jo.get("data");
		}
		return null;
	}

	
	public static boolean pullVars(String domain,String env, String appId, String appCode, String instanceId,
			Map<String,CfgVarPullCallback> callbackMap) {
		String url = String.format(varPullUrl, domain, appId, appCode, instanceId, env);
		String json = HttpClientUtil.sendGet(url);
		if (Util.strIsEmpty(json)) {
			for(CfgVarPullCallback callback:callbackMap.values()) {
				if (callback != null) {
					callback.onReadFailed();
				}
				return false;
			}
		}
		JSONObject jo = (JSONObject) JSON.parse(json);
		if (jo.getBooleanValue("success")) {
			JSONArray data = (JSONArray) jo.get("data");
			for (Object o : data) {
				JSONObject vo = (JSONObject) o;
				String k = vo.getString("name");
				String v = vo.getString("value");
				String g = vo.getString("group");
				CfgVarPullCallback callback=callbackMap.get(g);
				if (callback != null && callback.callback(k, v, g)) {
					continue;
				}
				System.getProperties().put(k, v);
			}
		}
		return true;
	}
	/**
	 * @param
	 * @param callback
	 */
	public static boolean pullVars(String domain, String appId, String appCode, String instanceId,
			CfgVarPullCallback callback) {
		String url = String.format(varPullUrl, domain, appId, appCode, instanceId);
		String json = HttpClientUtil.sendGet(url);
		if (Util.strIsEmpty(json)) {
			if (callback != null && callback.onReadFailed()) {
				return false;
			}
		}
		JSONObject jo = (JSONObject) JSON.parse(json);
		if (jo.getBooleanValue("success")) {
			JSONArray data = (JSONArray) jo.get("data");
			for (Object o : data) {
				JSONObject vo = (JSONObject) o;
				String k = vo.getString("name");
				String v = vo.getString("value");
				String g = vo.getString("group");
				if (callback != null && callback.callback(k, v, g)) {
					continue;
				}
				System.getProperties().put(k, v);
			}
		}
		return true;
	}

	public static boolean pullFiles(String domain, String env, String group, String appId, String appCode,
			String instanceId, String root, CfgFilePullCallback callback) {
		String url = String.format(filePullUrl, domain, env, group, appId, appCode, instanceId);
		String text = HttpClientUtil.sendGet(url);
		if (Util.strIsEmpty(text)) {
			if (callback.onReadFailed()) {
				return false;
			}
		}
		JSONObject jo = (JSONObject) JSON.parse(text);
		if (jo.getBooleanValue("success")) {
			JSONObject dd = (JSONObject) jo.get("data");
			JSONArray lt = (JSONArray) dd.get("list");
			for (Object o : lt) {
				JSONObject vo = (JSONObject) o;
				String k = vo.getString("code");
				String t = vo.getString("type");
				String p = vo.getString("deployPath");
				String v = vo.getString("content");
				if (v == null || "null".equals(v) || Util.strIsEmpty(v)) {
					continue;
				}
				if (Util.strIsEmpty(p)) {
					log.error("文件{}部署路径为空",k);
					continue;
				}
				String fp = new StringBuilder(root).append(p).toString();
				if ("binary".equalsIgnoreCase(vo.getString("encoding"))) {
					HttpClientUtil.downloadFile(String.format(fileDownloadUrl, domain, v, k), fp, 1000);
					continue;
				}
				File f = new File(fp);
				FileUtil.makePath(f.getParent());
				log.info("Write pulled config file {} to {}", fp, f.getAbsoluteFile());
				try {
					FileUtil.write(f, v);
				} catch (Exception e) {
					log.error("Error on write temp config file {}", fp, e);
				}
				callback.callback(k, t, v, p);
			}
		}
		return true;
	}

	public static void main(String[] args) {
		ConfigHttpPuller.pullFiles("localhost", "dev1cd", "default", //
				"8a908cf38b224287018b6080e60b75fc", "sc6kd-data-agg-rt-decrypt", //
				"xxxxx", "tmp", new CfgFilePullCallback() {
					@Override
					public boolean onReadFailed() {
						// 从配置中心拉取失败时执行，返回true表示中断执行
						return true;
					}

					@Override
					public boolean callback(String code, String type, String content, String path) {
						//
						return false;
					}
				});
	}
}